﻿using AutoMapper;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Newtonsoft.Json;
using Standard;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Workflow.Application.Dto;
using Workflow.Application.Dto.Input;
using Workflow.Application.Dto.Output;
using Workflow.Application.Step;
using Workflow.Domain;
using Workflow.Domain.Model;
using WorkflowCore.Interface;
using WorkflowCore.Models.DefinitionStorage.v1;
using WorkflowCore.Services.DefinitionStorage;
using Yitter.IdGenerator;

namespace Workflow.Application
{
    public class WorkflowService : IWorkflowService
    {
        private readonly WorkflowContext db;
        private readonly IMapper mapper;
        private readonly IDefinitionLoader loader;
        private readonly IWorkflowRegistry registry;
        private readonly IWorkflowHost host;

        public WorkflowService(WorkflowContext db,IMapper mapper,IDefinitionLoader loader,IWorkflowRegistry registry,IWorkflowHost host)
        {
            this.db = db;
            this.mapper = mapper;
            this.loader = loader;
            this.registry = registry;
            this.host = host;
        }
        /// <summary>
        /// 添加流程定义
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public ApiResult<int> AddDefinition(DefinitionInput input)
        {
            var model=mapper.Map<DefinitionModel>(input);
            model.Steps=JsonConvert.SerializeObject(input.Steps);
            db.definition.Add(model);
            db.SaveChanges();

            return new ApiResult<int> {Code=ApiCode.Success,ResultData=1,Message="添加定义成功" };
        }
        /// <summary>
        /// 审批
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> Audit(AuditInput input)
        {
           var audit=db.audit.FirstOrDefault(x=>x.WorkflowId==input.WorkflowId&&x.AuditUserId==input.AuditUserId&&!x.Status);
            audit.Status = true;
            audit.AuditOperation = input.AuditOperation;
            audit.Remark = input.Remark;
            db.SaveChanges();
           await host.PublishEvent("MyEvent",input.WorkflowId,input.Remark);
            return new ApiResult<int> {Code=ApiCode.Success,ResultData=1,Message="审批成功" };
        }

        /// <summary>
        /// 显示流程定义
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ApiResult<List< DefinitionModel>> GetAll()
        {
            return new ApiResult<List<DefinitionModel>> { Code = ApiCode.Success, Message = "成功", ResultData = db.definition.Where(x => !x.IsDeleted).ToList() };
        }
        /// <summary>
        /// 我的代办列表
        /// </summary>
        /// <param name="auditusername"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ApiResult<List<AuditModel>> GetAudit(string auditusername)
        {
            var model=db.audit.Where(x=>!x.Status&&x.AuditUserName==auditusername).ToList();
            return new ApiResult<List<AuditModel>> { Code = ApiCode.Success,ResultData=model,Message="成功" };
        }

        /// <summary>
        /// 审批实例列表
        /// </summary>
        /// <param name="shuju"></param>
        /// <param name="yema"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public ApiPaging<InstanceOutput> GetInstance(int shuju, int yema,string name,string rolename)
        {
            var model = db.instance.Where(x => x.ApplicationUserName == name || rolename == "管理员");
            var output=mapper.Map<List< InstanceOutput>>(model);

            
            return new ApiPaging<InstanceOutput> { Code = ApiCode.Success,PageDatas=output.Skip((yema-1)*shuju).Take(shuju).ToList(),Message="成功",TotalCount=output.Count(),TotalPage=(int)Math.Ceiling(output.Count()*1.0/shuju) };
        }

        /// <summary>
        /// 流程注册
        /// </summary>
        /// <param name="model"></param>
        public void LoaderDefinition(DefinitionModel model)
        {
            if (registry.IsRegistered(model.DefinitionId, model.Version)) 
            {
                return;
            }
            DefinitionSourceV1 source = new DefinitionSourceV1()
            {
                Id = model.DefinitionId,
                Description=model.Title,
                Version=model.Version,
                DataType=$"{typeof(Dictionary<string,object>).FullName},{typeof(Dictionary<string,object>).Assembly.FullName}"
            };
            var step = JsonConvert.DeserializeObject<List<StepNode>>(model.Steps);
            StepSourceV1 start = new StepSourceV1() 
            {
                Id=nameof(StartStep),
                Name="发起",
                NextStepId=step.First().StepId,
                StepType=$"{typeof(StartStep).FullName},{typeof(StartStep).Assembly.FullName}"
            };
            source.Steps.Add(start);

            foreach (var s in step) 
            {
                StepSourceV1 audit = new StepSourceV1()
                {
                    Id = s.StepId,
                    Name =s.StepName,
                    NextStepId = s.NextStepId,
                    StepType = $"{typeof(AuditStep).FullName},{typeof(AuditStep).Assembly.FullName}"
                };
                audit.Inputs.TryAdd("AuditUserId",$"\"{s.AuditUserId}\"");
                audit.Inputs.TryAdd("AuditUserName",$"\"{s.AuditUserName}\"");
                source.Steps.Add(audit);
            }

            StepSourceV1 end = new StepSourceV1()
            {
                Id = nameof(EndStep),
                Name = "结束",
                StepType = $"{typeof(EndStep).FullName},{typeof(EndStep).Assembly.FullName}"
            };
            source.Steps.Add(end);
            var json=JsonConvert.SerializeObject(source);
            loader.LoadDefinition(json, Deserializers.Json);
        }
        /// <summary>
        /// 发布流程接口
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ApiResult<int>> StartAudit(StartAuditInput input)
        {
            var data=JsonConvert.DeserializeObject<Dictionary<string,object>>(JsonConvert.SerializeObject(input));
            var workflowid = await host.StartWorkflow(input.DefinitionId, input.Version, data);
            db.instance.Add(new() 
            {
                ID=YitIdHelper.NextId().ToString(),
                ApplicationUserName=input.UserName,
                DefinitionId=input.DefinitionId,
                WorkflowId=workflowid,
                AuditUserName=string.Empty,
                StepName=string.Empty,
                IsDeleted=false,
                Remark="处理中",
                Title=input.Title,
            });
            db.SaveChanges();
            return new ApiResult<int> 
            {
                Code=ApiCode.Success,
                ResultData=1,
                Message="发布申请成功"
            };
        }



    }
}
